﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;

namespace Bohdan.Arch.Messaging.Utilities
{
    class ClosingParameters
    {
        public bool ClosingStarted;
        public bool ClosingAllowed;
        public MessagingBus Bus;
        public GeneralExitMessage ExitMessage;
        public Action OnClosing;
    }

    public class ClosingHelper
    {


        // Using a DependencyProperty as the backing store for ClosingStarted.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ClosingParametersProperty =
            DependencyProperty.Register("ClosingParameters", typeof(ClosingParameters), typeof(DependencyObject));

        public static void ImplementClosing(Window window, MessagingBus bus, GeneralExitMessage exitMessage, Action onClosing)
        {
#if DEBUG
            if (bus == null)
                throw new ArgumentNullException("bus");
            if (exitMessage == null)
                throw new ArgumentNullException("exitMessage");
#endif
            var p = new ClosingParameters()
            {
                ClosingStarted = false,
                ClosingAllowed = false,
                Bus = bus,
                ExitMessage = exitMessage,
                OnClosing = onClosing
            };

            window.SetValue(ClosingParametersProperty, p);
            window.Closing += new CancelEventHandler(window_Closing);
        }

        public static void ExplicitClose(Window window)
        {
            var p = (ClosingParameters)window.GetValue(ClosingParametersProperty);
            p.ClosingAllowed = true;
            window.Close();
            p.Bus.DisposeAsync();
        }

        static void window_Closing(object sender, CancelEventArgs e)
        {
            var w = (Window)sender;
            var p = (ClosingParameters)w.GetValue(ClosingParametersProperty);

            if (p.ClosingAllowed)
                return;

            e.Cancel = true;

            if (p.ClosingStarted)
                return;

            if (p.OnClosing != null)
                p.OnClosing();

            p.ClosingStarted = true;

            p.Bus.PostShuttingDownMessageAsync(p.ExitMessage);
        }
    }
}
